/// Text Overlay Application: XMLParser Class
/// This class contains a custom XML parser used to process synchronization
/// messages faster.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;

namespace TextOverlay
{
    struct CXMLParser
    {
        public List<string> XmlTree;
        private int SelectedNode;


        /// <summary>
        /// Creates a new instance of the custom XMLParser
        /// </summary>
        /// <param name="Size"></param>
        public CXMLParser(int Size)
        {
            XmlTree = new List<string>();
            SelectedNode = -1;
        }
        
        /// <summary>
        /// Clears the content of the XmlTree
        /// </summary>
        public void Nulle()
        {
            XmlTree.Clear();
            XmlTree = null;
        }

        /// <summary>
        /// Loads the content of a XML stream into the Parser's XML tree
        /// </summary>
        /// <param name="LongString">String containing the XML document</param>
        public void Parse(string LongString)
        {
            try
            {
                if (XmlTree == null) XmlTree = new List<string>();

                XmlTree.Clear();
                int start = 0;
                int stop = 0;
                while (true)
                {
                    stop = LongString.IndexOf(">", start);
                    if (stop < 0)
                    {
                        XmlTree.Add(LongString.Substring(start, LongString.Length - start));
                        return;
                    }
                    else
                    {
                        XmlTree.Add(LongString.Substring(start + 1, stop - start - 1));
                        start = stop + 1;
                    }
                }
            }
            catch
            {
                Track.LogInfo("Error in Sax Parser (Exception)");
            }
        }

        /// <summary>
        /// Retrieves the list of nodes contained in the XML document
        /// </summary>
        /// <param name="xml">String containing the XML document</param>
        /// <param name="Node">The name of the node to list</param>
        /// <returns>The number of nodes found</returns>
        public int GetNodeList(string xml, string Node)
        {
            XmlTree = new List<string>();
            XmlTree.Clear();
            int start = xml.IndexOf("<" + Node);
            int stop = 0;
            int nodes = 0;
            while (true)
            {
                stop = xml.IndexOf("</" + Node + ">", start);
                if (stop < 0)
                {
                    XmlTree.Add("<" + xml.Substring(start, xml.Length - start) + "</Combo>");
                    nodes++;
                    return nodes;
                }
                else
                {
                    XmlTree.Add("<" + xml.Substring(start + 1, stop - start - 1) + "</Combo>");
                    start = stop + 1;
                    nodes++;
                }
            }

        }

        /// <summary>
        /// Retrieves the information of a given node from the XmlTree
        /// </summary>
        /// <param name="Node">Name of the Node to retrieve</param>
        /// <returns>String containing the inner xml text of the node</returns>
        public string GetNode(string Node)
        {
            if (XmlTree.Count > 0)
            {
                for (int x = 0; x < XmlTree.Count; x++)
                {
                    if (XmlTree[x].Contains(Node) == true)
                        return XmlTree[x];
                }
            }
            else
                return "";
            return "";
        }

        /// <summary>
        /// Selects an Xml Node from the XmlTree to handle. This function selects the first
        /// occurence of the requested node in the XmlTree.
        /// </summary>
        /// <param name="Node">Name of the Node</param>
        /// <returns>String containing the inner xml text of the node</returns>
        public bool SelectNode(string Node)
        {
            if (XmlTree.Count > 0)
            {
                for (int x = (SelectedNode + 1); x < XmlTree.Count; x++)
                {
                    if (XmlTree[x].Contains(Node) == true)
                    {
                        SelectedNode = x;
                        return true;
                    }
                }

                for (int x = 0; x < (SelectedNode + 1); x++)
                {
                    if (XmlTree[x].Contains(Node) == true)
                    {
                        SelectedNode = x;
                        return true;
                    }
                }
            }
            SelectedNode = -1;
            return false;
        }

        /// <summary>
        /// Moves the handle to the next node in the XmlTree
        /// </summary>
        /// <returns>True if there is a next node in the XmlTree</returns>
        public bool SelectNextNode()
        {
            if ((XmlTree.Count - 1) > SelectedNode)
            {
                SelectedNode++;
                return true;
            }
            return false;
        }

        /// <summary>
        /// Moves the handle to the previous node in the XmlTree
        /// </summary>
        /// <returns>True if there is a previous node in the XmlTree</returns>
        public bool SelectPrevNode()
        {
            if (SelectedNode > 0)
            {
                SelectedNode--;
                return true;
            }
            return false;
        }

        /// <summary>
        /// Retrieves the inner xml text of a given attribute in the Xml node currently pointed by the XmlTree handler
        /// </summary>
        /// <param name="key">The name of the attribute</param>
        /// <returns>a string containing the inner xml text</returns>
        public string GetAttribute(string key)
        {
            if(SelectedNode > -1)
            {
                int start = XmlTree[SelectedNode].IndexOf(key);
                if (start > -1)
                {
                    int stop = XmlTree[SelectedNode].IndexOf(" ", start);
                    if(stop > -1)
                        return XmlTree[SelectedNode].Substring(start + key.Length + 2, stop - (start + key.Length + 3));
                    else
                        return XmlTree[SelectedNode].Substring(start + key.Length + 2, XmlTree[SelectedNode].Length - (start + key.Length + 4));
                }
                return "";
            }
            return "";
        }


    }
}
